package control

import (
	"JVM/Jvmgo/GoToJVM/instructions/base"
	"JVM/Jvmgo/GoToJVM/runtimeData"
)

/*
	switch语法相关实现指令，如若case值可以编码成一个索引表则用tableswitch否则使用lookupswitch
*/

type TABLE_SWITCH struct {
	defaultOffset int32
	low           int32
	high          int32
	jumpOffsets   []int32
}

func (self *TABLE_SWITCH) FetchOperands(reader *base.BytecodeReader) {
	reader.SkipPadding() // 用以确保defaultOffset在字节码中华的地址是4的倍数
	self.defaultOffset = reader.ReadInt32()
	self.low = reader.ReadInt32()
	self.high = reader.ReadInt32()
	jumpOffsetsCount := self.high - self.low + 1
	self.jumpOffsets = reader.ReadInt32s(jumpOffsetsCount)
}

/*
从操作数栈顶弹出一个index，如果他在(low < index < high)这个范围内，
则使用从jumpOffsets中查出偏移量进行跳转，否则使用默认偏移量
*/
func (self *TABLE_SWITCH) Execute(frame *runtimeData.Frame) {
	index := frame.OperandStack().PopInt()
	var offset int
	if index > self.low && index < self.high {
		offset = int(self.jumpOffsets[index-self.low])
	} else {
		offset = int(self.defaultOffset)
	}
	base.Branch(frame, offset)
}
